﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;

namespace Game.Map
{
    public class GamePath
    {
        readonly Collection<Point> _points;
        
        public GamePath()
        {
            _points = new Collection<Point>();
        }
        
        public GamePath(Point start)
        {
            _points = new Collection<Point> {start};
        }
        
        public GamePath(Point start, Point end)
        {
            _points = new Collection<Point> {start, end};
        }

        public static GamePath CreateDirectPath(Point start, Point end)
        {
            var path = new GamePath();
            path.Points.Add(start);

            var next = start;
            while (next != end)
            { 
                if (next.X != end.X)
                {
                    next.X += (next.X > end.X ? -1 : 1);
                }
                if (next.Y != end.Y)
                {
                    next.Y += (next.Y > end.Y ? -1 : 1);
                }

                path.Points.Add(next);
            }

            return path;
        }
        
        public GamePath(IEnumerable<Point> points)
        {
            var list = new List<Point>(points);
            _points = new Collection<Point>(list);
        }
        
        public Collection<GamePath> Split()
        {
            var result = new Collection<GamePath>();
            
            var workingSet = new Collection<Point>();
            foreach (var point in _points) 
            {
                workingSet.Add(point);
                if (workingSet.Count > 2)
                {
                    workingSet.RemoveAt(0);
                }
                if (workingSet.Count > 1)
                {
                    var path = new GamePath(workingSet);
                    result.Add(path);
                }
            }
            
            return result;
        }

        public GamePath FirstStep
        {
            get
            {
                if (Points.Count < 2)
                {
                    return null;
                }

                return new GamePath(new Collection<Point> { Points[0], Points[1] });
            }
        }

        public Collection<Point> Points
        {
            get { return _points; }
        }
        
        public double Distance
        {
            get { return (_points.Count - 1); }
        }

        public Point LastPoint
        {
            get 
            {
                if (_points.Count == 0)
                {
                    return new Point(-1, -1);
                }
                
                return _points[_points.Count - 1];
            }
        }
        
        public Point FirstPoint
        {
            get 
            {
                if (_points.Count == 0)
                {
                    return new Point(-1, -1);
                }
                
                return _points[0];
            }
        }
        
        public Point SecondToLastPoint
        {
            get 
            {
                if (_points.Count < 2)
                {
                    return new Point(-1, -1);
                }
                
                return _points[_points.Count - 2];
            }
        }
        
        public override string ToString()
        {
            string s = "[";
            foreach (Point point in _points) 
            {
                s += "(" + point.ToString() + ")";
            }
            s += "]";
            return s;
        }

    }
}
